import logging
from fastapi.exceptions import RequestValidationError
from fastapi import HTTPException, Request
from sqlalchemy.exc import SQLAlchemyError, ArgumentError
from commons.BaseResponse import BaseResponse
from fastapi.responses import JSONResponse

from main import app

logger = logging.getLogger(__name__)


# 自定义异常处理

@app.exception_handler(SQLAlchemyError)
async def sqlalchemy_error_handler(request: Request, exc: SQLAlchemyError):
    error_detail = {
        "error": "数据库操作失败",
        "detail": str(exc)
    }

    try:
        if isinstance(exc, ArgumentError):
            logger.error(
                "SQL 参数错误: %s - Path: %s",
                str(exc),
                request.url.path
            )
            error_detail["type"] = "参数错误"
        else:
            # 对于其他 SQLAlchemyError，尝试获取更多信息
            statement = getattr(exc, 'statement', None)
            orig = getattr(exc, 'orig', None)
            params = getattr(exc, 'params', None)

            logger.error(
                "SQL 错误: %s - Path: %s - Detail: %s - Param: %s \n %s",
                str(statement) if statement else "N/A",
                request.url.path,
                str(orig) if orig else "N/A",
                str(params) if params else "N/A",
                error_detail
            )
            error_detail.update({
                "statement": str(statement) if statement else None,
                "original_error": str(orig) if orig else None
            })

    except Exception as e:
        logger.error("记录SQL错误时发生异常: %s", str(e))

    return JSONResponse(
        status_code=400,
        content=error_detail
    )


@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
    logger.error(
        "验证失败 - Path: %s - Errors: %s - Body: %s",
        request.url.path,
        exc.errors(),
        exc.body
    )
    return JSONResponse(
        status_code=422,
        content=BaseResponse.error(
            code=422,
            message="验证失败",
            data=exc.errors()
        ).dict()
    )


@app.exception_handler(HTTPException)
async def http_exception_handler(request: Request, exc: HTTPException):
    logger.error(
        f"HTTP error: {exc.detail}",
        extra={
            "path": request.url.path,
            "method": request.method,
            "status_code": exc.status_code,
        }
    )
    return JSONResponse(
        status_code=500,
        content=BaseResponse.error(
            code=500,
            message=str(exc.detail)
        ).dict()
    )


# 异常处理器
@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
    logger.error(
        f"Unhandled exception: {str(exc)}",
        exc_info=True,
        extra={
            "path": request.url.path,
            "method": request.method,
            "query_params": dict(request.query_params),
        }
    )
    return JSONResponse(
        status_code=500,
        content=BaseResponse.error(
            code=500,
            message=str(exc.args)
        ).dict()
    )
